package cheme.ProcessEditor.DirectEdit;

import java.lang.reflect.Constructor;

import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.tools.CellEditorLocator;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ICellEditorListener;
import org.eclipse.jface.viewers.ICellEditorValidator;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.List;

import cheme.ProcessEditor.LeafFigureNavigator;

public class ChemeSelectionDirectEditManager extends
		ChemeExtendedDirectEditManager
{
	String[] items;

	public ChemeSelectionDirectEditManager(GraphicalEditPart source,
			Class editorType, String[] items, CellEditorLocator locator,
			Label label, ICellEditorValidator validator)
	{
		super(source, editorType, locator, label, validator);

		this.items = items;
	}

	protected ListCellEditor getCellEditor()
	{
		return (ListCellEditor)super.getCellEditor();
	}

	/**
	 * Creates the cell editor on the given composite. The cell editor is
	 * created by instantiating the cell editor type passed into this
	 * DirectEditManager's constuctor.
	 * 
	 * @param composite
	 *            the composite to create the cell editor on
	 * @return the newly created cell editor
	 */
	protected CellEditor createCellEditorOn(Composite composite)
	{
		CellEditor editor = null;

		try
		{
			Constructor constructor = editorType.getConstructor(new Class[] {Composite.class, String[].class });
			editor = (CellEditor)constructor.newInstance(new Object[] {composite, items});
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}

		return editor;
	}

	/**
	 * @see org.eclipse.gef.tools.DirectEditManager#initCellEditor()
	 */
	protected void initCellEditor()
	{
		List control = getCellEditor().getControl();

		control.addMouseListener(new MouseListener()
		{
			public void mouseDoubleClick(MouseEvent e)
			{
				setDirty(true);
				commit();
				LeafFigureNavigator.navigateTo((GraphicalEditPart)getEditPart());
			}

			public void mouseDown(MouseEvent e) {}
			public void mouseUp(MouseEvent e) {}
		});

		control.addKeyListener(new KeyListener()
		{
			public void keyPressed(KeyEvent e) {}

			public void keyReleased(KeyEvent e)
			{
				if(e.keyCode == 13) // return key
				{
					setDirty(true);
					commit();
					LeafFigureNavigator.navigateTo((GraphicalEditPart)getEditPart());
				}
			}
		});

		getCellEditor().addListener(new ICellEditorListener()
		{
			public void applyEditorValue() {}

			public void cancelEditor()
			{
				LeafFigureNavigator.navigateTo((GraphicalEditPart)getEditPart());
			}

			public void editorValueChanged(boolean oldValidState, boolean newValidState)
			{
			}
		});

		// set the initial value of the editor

		try
		{
			originalValue = this.label.getText();
			getCellEditor().setValue(0);

			/*
			 * Give the editor it's list items
			 */
			getCellEditor().setItems(items);

			// calculate the font size of the underlying
			IFigure figure = ((GraphicalEditPart)getEditPart()).getFigure();
			figureFont = figure.getFont();
			FontData data = figureFont.getFontData()[0];
			Dimension fontSize = new Dimension(0, data.getHeight());

			// set the font to be used
			this.label.translateToAbsolute(fontSize);
			data.setHeight(fontSize.height);
			figureFont = new Font(null, data);

			// set the validator for the CellEditor
			getCellEditor().setValidator(validator);

			control.setFont(figureFont);
			
			control.setSelection(0);
			control.setFocus();

			LeafFigureNavigator.deselect((GraphicalEditPart)getEditPart());
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
}
